package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;


@Slf4j
public class NettySocksClientProxyServerRealHandler extends SimpleChannelInboundHandler<NettyByteBuf> {

    private final ChannelTypeAdapter channelTypeAdapter;

    public NettySocksClientProxyServerRealHandler(ChannelTypeAdapter channelTypeAdapter) {
        this.channelTypeAdapter = channelTypeAdapter;
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, NettyByteBuf nettyByteBuf) throws Exception {
        log.trace("开始写回客户端数据");
        // 结果下发
        byte[] bytes = nettyByteBuf.getData();
        log.debug("bytes.length:{}", bytes.length);
        log.debug("客户端socks代理服务端接收服务端真实服务数据:{}", new String(bytes));

        // 将数据返回给客户端
        NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
        nettyProxyMsg.setType(ProxyMessageType.SOCKS_REPORT_CLIENT_PROXY_SERVER_TRANSFER_RESPONSE_);
        nettyProxyMsg.setData(bytes);

        channelTypeAdapter.handler(ctx, nettyProxyMsg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.trace("代理服务器和目标服务器的连接已经断开，即将断开客户端和代理服务器的连接");
        Channel channel = ctx.channel();
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
        if (nextChannel.isActive()) {
            // 下发关闭请求
            NettyProxyMsg nettyProxyMsgClose = new NettyProxyMsg();
            nettyProxyMsgClose.setType(ProxyMessageType.SOCKS_DISTRIBUTE_CLIENT_PROXY_SERVER_TRANSFER_CLOSE_);
            nextChannel.writeAndFlush(nettyProxyMsgClose);

            nextChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("NettySocksClientProxyServerRealHandler exception", cause);
        ctx.close();
    }
}
